package com.wejoy.video.middle.station.data.service.system.impl;

import com.wejoy.video.middle.station.data.domain.system.SysDept;
import com.wejoy.video.middle.station.data.domain.system.SysResource;
import com.wejoy.video.middle.station.data.domain.system.SysUser;
import com.wejoy.video.middle.station.data.enums.dict.EnumStatus;
import com.wejoy.video.middle.station.data.enums.dict.EnumSysResourceType;
import com.wejoy.video.middle.station.data.mapper.system.ISysRoleOrderMapper;
import com.wejoy.video.middle.station.data.domain.system.SysRoleOrder;
import com.wejoy.video.middle.station.data.service.common.IIdWorkerService;
import com.wejoy.video.middle.station.data.service.evs.IEvsHttpService;
import com.wejoy.video.middle.station.data.service.system.ISysDeptService;
import com.wejoy.video.middle.station.data.service.system.ISysRoleOrderService;
import com.wejoy.video.middle.station.data.util.WJAssert;
import com.wejoy.video.middle.station.data.vo.RespJSON;
import com.wejoy.video.middle.station.data.vo.api.DeptNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统-工单权限关联表
 *
 * @author admin
 * @date 2024年03月31日 21:52:42
 */
@Service
public class SysRoleOrderServiceImpl implements ISysRoleOrderService {
    @Autowired
    private ISysRoleOrderMapper sysRoleOrderMapper;
    @Autowired
    private IIdWorkerService idWorkerService;
    @Autowired
    private IEvsHttpService evsHttpService;
    @Autowired
    private ISysDeptService deptService;

    @Override
    public void save(SysRoleOrder req, String operator) {
        req.setOperator(operator);
        if (null == req.getId()) {
            insertSelective(req);
        } else {
            updateSelectiveById(req);
        }
    }

    @Override
    public void addDeptRole(SysRoleOrder req, SysUser sysUser, String operator) {
        List<Long> dptIds = req.getDptIds();
        sysRoleOrderMapper.deleteByUserId(sysUser.getId());
        if (CollectionUtils.isEmpty(dptIds) && req.getRoleType()==2) {
            return;
        }
        if (req.getRoleType()!=2) {
            SysRoleOrder sysRoleOrder = new SysRoleOrder();
            sysRoleOrder.setUserId(sysUser.getId());
            sysRoleOrder.setOperator(operator);
            sysRoleOrder.setDeptId(req.getRoleType());
            sysRoleOrder.setId(idWorkerService.getNextId());
            sysRoleOrder.setStatus(EnumStatus.NEW.getCode());
            sysRoleOrderMapper.insertSelective(sysRoleOrder);
            return;
        }
        List<SysRoleOrder> list = dptIds.parallelStream().map(item -> {
            SysRoleOrder sysRoleOrder = new SysRoleOrder();
            sysRoleOrder.setUserId(sysUser.getId());
            sysRoleOrder.setOperator(operator);
            sysRoleOrder.setDeptId(item);
            sysRoleOrder.setId(idWorkerService.getNextId());
            sysRoleOrder.setStatus(EnumStatus.NEW.getCode());
            return sysRoleOrder;
        }).collect(Collectors.toList());
        sysRoleOrderMapper.batchInsert(list);
    }

    @Override
    public int insertSelective(SysRoleOrder req) {
        req.setId(idWorkerService.getNextId());
        req.setStatus(EnumStatus.NEW.getCode());
        checkStringLength(req, false);
        return sysRoleOrderMapper.insertSelective(req);
    }

    @Override
    public int updateSelectiveById(SysRoleOrder sysRoleOrder) {
        WJAssert.notNull(sysRoleOrder, "入参对象不能为空");
        WJAssert.notNull(sysRoleOrder.getId(), "id参数错误");
        SysRoleOrder where = new SysRoleOrder();
        where.setId(sysRoleOrder.getId());
        return sysRoleOrderMapper.updateSelective(sysRoleOrder, where);
    }

    @Override
    public int getCount(SysRoleOrder sysRoleOrder) {
        checkStringLength(sysRoleOrder, true);
        return sysRoleOrderMapper.getCount(sysRoleOrder);
    }

    @Override
    public SysRoleOrder getOneById(Long id) {
        WJAssert.notNull(id, "id参数错误");
        SysRoleOrder where = new SysRoleOrder();
        where.setId(id);
        return sysRoleOrderMapper.getOne(where);
    }

    @Override
    public List<SysRoleOrder> getList(SysRoleOrder sysRoleOrder) {
        checkStringLength(sysRoleOrder, true);
        return sysRoleOrderMapper.getList(sysRoleOrder);
    }

    @Override
    public List<SysRoleOrder> getPageList(SysRoleOrder sysRoleOrder) {
        checkStringLength(sysRoleOrder, true);
        return sysRoleOrderMapper.getPageList(sysRoleOrder);
    }

    @Override
    public void audit(Long id, String operator) {
        SysRoleOrder req = new SysRoleOrder();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.AUDIT.getCode());
        updateSelectiveById(req);
    }

    @Override
    public void unaudit(Long id, String operator) {
        SysRoleOrder req = new SysRoleOrder();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.NEW.getCode());
        updateSelectiveById(req);
    }

    @Override
    public void delete(Long id, String operator) {
        SysRoleOrder req = new SysRoleOrder();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.DEL.getCode());
        updateSelectiveById(req);
    }

    @Override
    public Map<String,List<Long>> getOrderDeptIdListByUserId(Long id,SysUser sysUser) {

        Map<String, List<Long>> resultMap = new HashMap<>(2);
        resultMap.put("checkedTreeList", new ArrayList<>());
        resultMap.put("treeList", new ArrayList<>());
        SysRoleOrder sysRoleOrder = new SysRoleOrder();
        sysRoleOrder.setUserId(id);
        //查询这个角色所拥有的所有部门资源
        List<SysRoleOrder> list = getList(sysRoleOrder);
        if (CollectionUtils.isEmpty(list)) {
            return resultMap;
        }
        List<Long> listIds = new ArrayList<>();
        for (SysRoleOrder roleOrder : list) {
            listIds.add(roleOrder.getDeptId());
        }
        SysDept evsApiDept = new SysDept();
        evsApiDept.setParentId(-1);
        evsApiDept.setIncludeLower(true);
        List<DeptNode> deptNodes = deptService.convertToDesiredFormat(evsHttpService.getDepartmentsJson(evsApiDept, sysUser.getToken()));
        //部门是否包含所有子类
        //过滤后的结果目录
        List<Long> catalogueResourceIdListResult = listIds.stream()
                .filter(item -> {
                    return isHasAllChildren(deptNodes, listIds);
                }).collect(Collectors.toList());
        resultMap.put("checkedTreeList",catalogueResourceIdListResult);
        resultMap.put("treeList", listIds);
        return resultMap;
    }

    /**
     * 菜单是否包含所有子类
     *
     * @param parentNode
     * @param list
     * @return
     */
    private boolean isHasAllChildren(List<DeptNode> parentNode, List<Long> list) {
        for (Long l : list) {
            return containsAllChildrenIds(parentNode,l, (Set<Long>) list);
        }
        return false;
    }

    public boolean containsAllChildrenIds(List<DeptNode> deptNodes, Long parentId, Set<Long> deptIdSet) {
        // 找到给定部门ID的节点
        DeptNode parentNode = findDeptNodeById(deptNodes, parentId);
        if (parentNode == null) {
            return false; // 如果找不到对应的节点，则返回false
        }

        // 递归检查所有子节点
        return containsAllChildren(parentNode, deptIdSet);
    }

    private boolean containsAllChildren(DeptNode parentNode, Set<Long> deptIdSet) {
        // 遍历子节点
        for (DeptNode childNode : parentNode.getChildren()) {
            Long childId = (long) childNode.getId();
            if (!deptIdSet.contains(childId)) {
                return false; // 如果子节点不在部门ID集合中，则返回false
            }
            // 递归检查子节点的子节点
            if (!containsAllChildren(childNode, deptIdSet)) {
                return false; // 如果子节点的子节点中有任何一个不在部门ID集合中，则返回false
            }
        }
        return true; // 如果所有子节点都在部门ID集合中，则返回true
    }

    private DeptNode findDeptNodeById(List<DeptNode> deptNodes, Long id) {
        for (DeptNode node : deptNodes) {
            if (node.getId()==id) {
                return node; // 找到匹配的节点
            }
            // 递归搜索子节点
            DeptNode found = findDeptNodeById(node.getChildren(), id);
            if (found != null) {
                return found; // 如果在子节点中找到匹配的节点，则返回找到的节点
            }
        }
        return null; // 如果找不到匹配的节点，则返回null
    }


    /**
     * 参数校验注解默认使用的方法
     */
    private void checkStringLength(SysRoleOrder sysRoleOrder, boolean nullAble) {
        WJAssert.notNull(sysRoleOrder, "入参对象不能为空");
        WJAssert.limitMaxLength(sysRoleOrder.getOperator(), true, 255, "操作人不合法!");
        WJAssert.limitMaxLength(sysRoleOrder.getRemark(), true, 255, "备注不合法!");
    }
}
